package widget.bar;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

import library.utils.DisplayUtil;


/**
 * Created by Mr.Fan on 2016/11/11.
 */

public class NavigationBar extends Bar<NavigationBar> {

    protected NavigationBar(@Nullable SystemBar systemBar) {
        super(systemBar);
    }

    public StatusBar statusBar() {
        return getSystemBar().statusBar();
    }


    protected void commit(Window window) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            setNavigationBar(window, this);
        }
    }


    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void setNavigationBar(@NonNull Window window, @NonNull NavigationBar bar) {
        if (window == null || bar == null)
            return;

        if (bar.isSupport()) {
            FlagCompat.setLayoutStable(window, true);
            FlagCompat.setLayoutHideNavigation(window, true);
            FlagCompat.setDrawsSystemBarBackground(window, true);
            FlagCompat.setTranslucentNavigation(window, true);
            addNavigationBarView(window, bar);
        } else {
            FlagCompat.setTranslucentNavigation(window, false);

            clearNavigationBarView(window);
            if (clearFitDrawable(window)) {
                FlagCompat.setLayoutHideNavigation(window, false);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//                window.addFlags(NAVIGATION_FLAG);
                window.setNavigationBarColor(Color.BLACK);
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void clearNavigationBarView(Window window) {
        final ViewGroup decorView = (ViewGroup) window.getDecorView();
        NavigationView navigationView = getView(decorView, NavigationView.class);
        if (navigationView != null) {
            decorView.removeView(navigationView);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private boolean clearFitDrawable(Window window) {
        View contentView = getSystemBar().getContentView();
        if (contentView != null) {
            return clearNavigationBarFitDrawable(contentView, 0);
        } else {
            final ViewGroup android_content = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
            return clearNavigationBarFitDrawable(android_content, 2);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void addNavigationBarView(Window window, NavigationBar bar) {
        /**
         * 处理颜色，透明度
         * 在 (id=Window.ID_ANDROID_CONTENT)view 中添加新的status view
         */
        View contentView = getSystemBar().getContentView();
        if (contentView != null) {
            clearNavigationBarView(window);
        } else {
            clearFitDrawable(window);
        }
        if (bar.isTransparent()) {
        } else if (bar.isTranslucent()) {
            setNavigationBarColor(window, getSystemBar().getMainColor(), 0xFF / 3);
        } else if (contentView == null) {
            setNavigationBarColor(window, bar.getColor(), bar.getAlpha());
        } else {// 处理多view
            final int navigationBarHeight = DisplayUtil.getNavigationBarHeight();
            FitDrawable fitDrawable = getFitDrawable(contentView.getBackground(), bar.getColor(), bar.getAlpha());
            fitDrawable.setLayerInsetBottom(1, navigationBarHeight);
            contentView.setBackground(fitDrawable);
            setMultiLayoutNavigationViewPadding(contentView, navigationBarHeight, true);
        }
    }

    protected final FitDrawable getFitDrawable(Drawable background, final Integer color, final Integer alpha) {
        FitDrawable origin = null;
        BarDrawable barDrawable = null;
        if (background == null) {
            background = new ColorDrawable(Color.BLACK);
        } else if (background instanceof FitDrawable) {
            origin = (FitDrawable) background;
            Drawable d0 = origin.getDrawable(0);
            background = origin.getDrawable(1);
            if (d0 instanceof BarDrawable)
                barDrawable = (BarDrawable) d0;
        }
        if (barDrawable == null)
            barDrawable = new BarDrawable();
        int c = alphaColor(color, alpha);
        barDrawable.setBottomColor(c);
        Drawable[] drawables = new Drawable[]{barDrawable.getDrawable(), background};
        FitDrawable fitDrawable = new FitDrawable(drawables);
        if (origin != null)
            fitDrawable.setLayerInset(1, 0, origin.getLayerInsetTop(), 0, origin.getLayerInsetBottom());
        return fitDrawable;
    }

    /**
     * @param view
     * @param depth view 向内遍历最大层次数
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private boolean clearNavigationBarFitDrawable(View view, int depth) {
        if (view == null || depth <= 0)
            return false;
        Drawable origin = view.getBackground();
        if (origin instanceof FitDrawable) {
            FitDrawable fitDrawable = (FitDrawable) origin;
            fitDrawable.setLayerInsetBottom(1, 0);
            setMultiLayoutNavigationViewPadding(view, fitDrawable.getLayerInsetBottom(), false);
            return true;
        } else if (view instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view;
            int count = viewGroup.getChildCount();
            for (int i = count - 1; i >= 0; i--) {
                View v = viewGroup.getChildAt(i);
                if (clearNavigationBarFitDrawable(v, depth--)) {
                    return true;
                }
            }
        }
        return false;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void setMultiLayoutNavigationViewPadding(View contentView, int navHeight, boolean show) {
        final ViewGroup container = (ViewGroup) contentView.getParent();
        if (container == null) {
            return;
        }
        View v = contentView;
        if (show) {
            if (v.getFitsSystemWindows())
                return;
            v.setPadding(
                    v.getPaddingLeft(),
                    v.getPaddingTop(),
                    v.getPaddingRight(),
                    v.getPaddingBottom() + navHeight);
        } else {
            v.setPadding(
                    v.getPaddingLeft(),
                    v.getPaddingTop(),
                    v.getPaddingRight(),
                    v.getPaddingBottom() - navHeight);
        }
    }

    private void setNavigationBarColor(Window window, Integer color, Integer alpha) {
        final ViewGroup decorView = (ViewGroup) window.getDecorView();
        NavigationView navigationView = getView(decorView, NavigationView.class);
        int calculateColor = alphaColor(color, alpha);
        if (navigationView != null) {
            navigationView.setBackgroundColor(calculateColor);
        } else {
            navigationView = createNavigationBarView(window, calculateColor);
            ViewGroup.LayoutParams lp = navigationView.getLayoutParams();
            if (decorView instanceof FrameLayout) {
                FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(lp);
                flp.gravity = Gravity.BOTTOM;
                navigationView.setLayoutParams(flp);
            } else if (decorView instanceof RelativeLayout) {
                RelativeLayout.LayoutParams rlp = (new RelativeLayout.LayoutParams(lp));
                rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                navigationView.setLayoutParams(rlp);
            } else {
                return;
            }
            decorView.addView(navigationView);
        }
    }

    private NavigationView createNavigationBarView(Window window, int color) {
        Context context = window.getContext();
        NavigationView navigationView = new NavigationView(context);
        int height = DisplayUtil.getNavigationBarHeight();
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, Math.max(0, height));
        navigationView.setLayoutParams(params);
        navigationView.setBackgroundColor(color);
        return navigationView;
    }

    /*
     * ******************************************************************************************
     * Inner Class 仅用于类型判断以避免重复添加view
     * ******************************************************************************************
     */

    private static final class NavigationView extends BarView {

        public NavigationView(Context context) {
            super(context);
        }
    }

}
